#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
完整测试套件运行器
运行所有测试并生成详细报告
"""

import sys
import os
import unittest
from io import StringIO
from pathlib import Path
import traceback
from datetime import datetime

# 添加项目根目录到路径
project_root = Path(__file__).parent
sys.path.insert(0, str(project_root))

# 导入所有测试模块
from test_core import *
from test_llm import *
from test_parsers import *
from test_video import *
from test_tts import *
from test_cli import *
from test_animation_additional import *
from test_integration import *


class TestResultCollector:
    """测试结果收集器"""

    def __init__(self):
        self.results = {}
        self.total_tests = 0
        self.total_failures = 0
        self.total_errors = 0
        self.total_skipped = 0
        self.total_success = 0
        self.execution_times = {}

    def add_result(self, module_name, result):
        """添加测试结果"""
        self.results[module_name] = {
            'tests': result.testsRun,
            'failures': len(result.failures),
            'errors': len(result.errors),
            'skipped': len(result.skipped),
            'success': result.testsRun - len(result.failures) - len(result.errors),
            'success_rate': (result.testsRun - len(result.failures) - len(result.errors)) / max(result.testsRun, 1) * 100,
            'is_success': len(result.failures) == 0 and len(result.errors) == 0,
        }
        self.total_tests += result.testsRun
        self.total_failures += len(result.failures)
        self.total_errors += len(result.errors)
        self.total_skipped += len(result.skipped)
        self.total_success += result.testsRun - len(result.failures) - len(result.errors)

    def add_execution_time(self, module_name, time):
        """添加执行时间"""
        self.execution_times[module_name] = time

    def get_overall_success_rate(self):
        """获取总体成功率"""
        if self.total_tests == 0:
            return 0
        return (self.total_success / self.total_tests) * 100

    def generate_report(self):
        """生成报告"""
        report = []
        report.append("=" * 80)
        report.append("完整测试套件执行报告")
        report.append("=" * 80)
        report.append(f"执行时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
        report.append("")

        # 总体统计
        report.append("总体统计:")
        report.append(f"  总测试数: {self.total_tests}")
        report.append(f"  成功: {self.total_success}")
        report.append(f"  失败: {self.total_failures}")
        report.append(f"  错误: {self.total_errors}")
        report.append(f"  跳过: {self.total_skipped}")
        report.append(f"  成功率: {self.get_overall_success_rate():.2f}%")
        report.append("")

        # 各模块详情
        report.append("各模块测试详情:")
        report.append("-" * 80)
        for module_name, result in self.results.items():
            status = "✓ PASS" if result['is_success'] else "✗ FAIL"
            report.append(f"\n{module_name}: {status}")
            report.append(f"  测试数量: {result['tests']}")
            report.append(f"  成功: {result['success']}")
            report.append(f"  失败: {result['failures']}")
            report.append(f"  错误: {result['errors']}")
            report.append(f"  成功率: {result['success_rate']:.2f}%")
            if module_name in self.execution_times:
                report.append(f"  执行时间: {self.execution_times[module_name]:.2f}秒")

        report.append("")
        report.append("=" * 80)

        return "\n".join(report)


def discover_and_run_tests(module_name, test_module, collector):
    """发现并运行测试"""
    print(f"\n{'=' * 80}")
    print(f"运行模块: {module_name}")
    print('=' * 80)

    # 创建测试套件
    loader = unittest.TestLoader()
    suite = loader.loadTestsFromModule(test_module)

    # 创建测试结果收集器
    stream = StringIO()
    runner = unittest.TextTestRunner(
        stream=stream,
        verbosity=2,
        buffer=True,
    )

    # 记录开始时间
    start_time = datetime.now()

    # 运行测试
    result = runner.run(suite)

    # 记录结束时间
    end_time = datetime.now()
    execution_time = (end_time - start_time).total_seconds()

    # 收集结果
    collector.add_result(module_name, result)
    collector.add_execution_time(module_name, execution_time)

    # 输出结果摘要
    print(f"\n{module_name} 测试结果:")
    print(f"  总计: {result.testsRun}")
    print(f"  成功: {result.testsRun - len(result.failures) - len(result.errors)}")
    print(f"  失败: {len(result.failures)}")
    print(f"  错误: {len(result.errors)}")
    print(f"  成功率: {(result.testsRun - len(result.failures) - len(result.errors)) / max(result.testsRun, 1) * 100:.2f}%")
    print(f"  执行时间: {execution_time:.2f}秒")

    # 输出失败的测试详情
    if result.failures:
        print(f"\n失败测试 ({len(result.failures)}):")
        for test, traceback_str in result.failures:
            print(f"  - {test}: {traceback_str.split('AssertionError:')[-1].strip() if 'AssertionError:' in traceback_str else 'Failed'}")

    # 输出错误的测试详情
    if result.errors:
        print(f"\n错误测试 ({len(result.errors)}):")
        for test, traceback_str in result.errors:
            print(f"  - {test}: {traceback_str.splitlines()[-1]}")

    return result


def main():
    """主函数"""
    print("开始运行完整测试套件...")
    print(f"项目根目录: {project_root}")

    # 创建结果收集器
    collector = TestResultCollector()

    # 定义要运行的测试模块
    test_modules = [
        ("核心模块 (test_core)", sys.modules["test_core"]),
        ("LLM模块 (test_llm)", sys.modules["test_llm"]),
        ("解析器模块 (test_parsers)", sys.modules["test_parsers"]),
        ("视频模块 (test_video)", sys.modules["test_video"]),
        ("TTS模块 (test_tts)", sys.modules["test_tts"]),
        ("CLI工具 (test_cli)", sys.modules["test_cli"]),
        ("动画模块 (test_animation_additional)", sys.modules["test_animation_additional"]),
        ("集成测试 (test_integration)", sys.modules["test_integration"]),
        ("时间同步系统 (test_time_sync)", sys.modules.get("test_time_sync")),
        ("流水线系统 (test_pipeline)", sys.modules.get("test_pipeline")),
        ("质量系统 (test_quality_system)", sys.modules.get("test_quality_system")),
        ("增强断点 (test_enhanced_checkpoint)", sys.modules.get("test_enhanced_checkpoint")),
        ("同步验证器 (test_sync_validator)", sys.modules.get("test_sync_validator")),
    ]

    # 运行每个测试模块
    for module_name, test_module in test_modules:
        if test_module is None:
            print(f"\n跳过模块: {module_name} (未找到)")
            continue

        try:
            discover_and_run_tests(module_name, test_module, collector)
        except Exception as e:
            print(f"\n错误: 无法运行模块 {module_name}")
            print(f"  异常: {str(e)}")
            traceback.print_exc()

    # 生成最终报告
    print("\n" + "=" * 80)
    print("最终测试报告")
    print("=" * 80)

    report = collector.generate_report()
    print(report)

    # 保存报告到文件
    report_file = project_root / "test_report.txt"
    with open(report_file, "w", encoding="utf-8") as f:
        f.write(report)
    print(f"\n报告已保存到: {report_file}")

    # 保存详细报告到JSON
    import json

    detailed_report = {
        "timestamp": datetime.now().isoformat(),
        "total_tests": collector.total_tests,
        "total_success": collector.total_success,
        "total_failures": collector.total_failures,
        "total_errors": collector.total_errors,
        "total_skipped": collector.total_skipped,
        "success_rate": collector.get_overall_success_rate(),
        "modules": {},
        "execution_times": collector.execution_times,
    }

    for module_name, result in collector.results.items():
        detailed_report["modules"][module_name] = result

    json_report_file = project_root / "test_report.json"
    with open(json_report_file, "w", encoding="utf-8") as f:
        json.dump(detailed_report, f, indent=2, ensure_ascii=False)
    print(f"详细报告已保存到: {json_report_file}")

    # 返回退出码
    if collector.get_overall_success_rate() == 100.0:
        print("\n🎉 所有测试通过! (100% 成功率)")
        return 0
    else:
        print(f"\n⚠️  部分测试失败. 成功率: {collector.get_overall_success_rate():.2f}%")
        return 1


if __name__ == "__main__":
    exit_code = main()
    sys.exit(exit_code)
